package com.nami.dispatcher.application.pmsg;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.nami.dispatcher.domain.gateway.UserGateway;
import com.nami.dispatcher.domain.model.NtfRecvModel;
import com.nami.dispatcher.domain.model.NtfSenderModel;
import com.nami.dispatcher.domain.service.DispatchCommonDomainService;
import com.nami.dispatcher.domain.service.DispatchPrivateDomainService;
import com.nami.dispatcher.facade.pmsg.ForwardPrivateMsgFacade;
import com.nami.dispatcher.facade.pmsg.request.PChatRequestCmd;
import com.nami.gate.external.basic.bo.ConnectedUserBO;
import com.nami.gate.external.basic.cache.user.DeviceInfo;
import com.nami.gate.external.basic.cache.user.UserDeviceRel;
import com.nami.im.network.model.message.v2.Message;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.nami.dispatcher.domain.manager.ThreadPoolManager.PDISPATCHERS;

@Slf4j
@Service
@RequiredArgsConstructor
public class ForwardPrivateMsgFacadeImpl implements ForwardPrivateMsgFacade {

    private final DispatchCommonDomainService commonDomainService;
    private final DispatchPrivateDomainService transDomainService;
    private final UserGateway userClient;

    @Override
    public void execute(PChatRequestCmd cmd) { //
        // 转发消息
        PDISPATCHERS.execute(() -> {
            try {
                TimeInterval timer = DateUtil.timer();
                ConnectedUserBO sender = cmd.getSender();
                //处理失败情况
                if (!cmd.isSuccess()) {
                    commonDomainService.failResp(cmd.getMessage(),
                        sender.getSessionId(), sender.getSessionId(), cmd.getErrCode());
                    return;
                }
                Message message = cmd.getMessage();
                ConnectedUserBO fromUser = cmd.getSender();

                log.info("[DISPATCHER-P] 转发器开始work. sender={}, messageId={}, clientMsgId={}",
                    fromUser.getUserId(), message.getMsgId(), message.getClientUid());

                commonDomainService.notifySender(buildSenderModel(cmd));
                transDomainService.notifyReceiver(buildRecvModel(cmd));
                if (timer.interval() > 500) {
                    log.warn("[DISPATCHER-P] 转发消息消耗过长，messageId={}, clientId={}, use:{}ms", message.getMsgId(),
                        message.getClientUid(), timer.interval());
                }
            } catch (Exception var2) {
                var2.printStackTrace();
                log.error("[DISPATCHER-P] ======单聊转发器出现问题了。。。======>{}", var2.getMessage());
            }
        });
    }

    private @NotNull NtfRecvModel buildRecvModel(PChatRequestCmd cmd) {
        ConnectedUserBO sender = cmd.getSender();
        Message message = cmd.getMessage();

        UserDeviceRel recvUser = userClient.getOnlUserDetailInfoById(sender.getAppKey(), message.getTargetId());

        NtfRecvModel recvModel = new NtfRecvModel();
        recvModel.setDevices(recvUser.getDeviceInfos());
        recvModel.setMessage(message);
        recvModel.setSenderId(sender.getUserId());

        ConnectedUserBO receiver = new ConnectedUserBO();
        receiver.setAppKey(recvUser.getAppKey());
        receiver.setNick(recvUser.getNick());
        receiver.setAvatar(recvUser.getAvatar());
        receiver.setUserId(recvUser.getUserId());

        recvModel.setReceiver(receiver);
        recvModel.setQos(cmd.getQos());
        return recvModel;
    }

    private @NotNull NtfSenderModel buildSenderModel(PChatRequestCmd cmd) {
        ConnectedUserBO sender = cmd.getSender();
        Message message = cmd.getMessage();
        // 获取from其他在线客户端
        List<DeviceInfo> senderOnlineDevices = userClient.getOnlineDevicesExceptThisDevice(sender.getAppKey(),
            message.getSenderId(), sender.getInstanceId());

        NtfSenderModel model = new NtfSenderModel();
        model.setMessage(message);
        model.setTag(sender.getConnectId());
        model.setSessionId(sender.getSessionId());
        model.setOtherClients(senderOnlineDevices);
        model.setAppKey(sender.getAppKey());

        model.setQos(cmd.getQos());
        return model;
    }

}
